﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace CornerMemo
{
    public class UIManager : MonoBehaviour
    {
        public static UIManager Instance;
        public UIManagerData uiData;
        
        private Dictionary<EnumUIForm, UIForm> _uiForms = new Dictionary<EnumUIForm, UIForm>();
        
        public RectTransform canvas;
        
        private void Awake()
        {
            if (Instance == null)
            {
                Instance = this;
                uiData.InitData();
                DontDestroyOnLoad(gameObject);
            }
            else
            {
                Destroy(gameObject);
            }
        }

        /// <summary>
        /// 打开UI窗体
        /// </summary>
        /// <param name="uiFormEnum">打开的窗口枚举</param>
        /// <param name="userData">用户传输给窗口的数据</param>
        /// <returns>打开后的UI窗口</returns>
        public UIForm OpenUIForm(EnumUIForm uiFormEnum, object userData = null)
        {
            if (_uiForms.ContainsKey(uiFormEnum))
            {
                _uiForms[uiFormEnum].OnOpen(userData);
                return _uiForms[uiFormEnum];
            }
            
            if (!uiData.UIFormsDict.ContainsKey(uiFormEnum))
            {
                Debug.LogError("UIFormData中没有对应的UIForm");
                return null;
            }
            
            _uiForms[uiFormEnum] = Instantiate(uiData.UIFormsDict[uiFormEnum].uiForm, canvas).GetComponent<UIForm>();
            _uiForms[uiFormEnum].OnInit();
            _uiForms[uiFormEnum].Order = uiData.UIFormsDict[uiFormEnum].order;
            _uiForms[uiFormEnum].OnOpen(userData);
            RefreshUIFormsOrder();
            return _uiForms[uiFormEnum];
        }
        /// <summary>
        /// 打开UI窗体
        /// </summary>
        /// <param name="uiFormEnum">打开的窗口枚举</param>
        /// <param name="userData">用户传输给窗口的数据</param>
        /// <typeparam name="T">打开的窗口类型</typeparam>
        /// <returns>打开后的UI窗口</returns>
        public T OpenUIForm<T>(EnumUIForm uiFormEnum, object userData = null) where T : UIForm
        {
            if (_uiForms.ContainsKey(uiFormEnum))
            {
                _uiForms[uiFormEnum].OnOpen(userData);
                return _uiForms[uiFormEnum] as T;
            }
            if (!uiData.UIFormsDict.ContainsKey(uiFormEnum))
            {
                Debug.LogError("UIFormData中没有对应的UIForm");
                return null;
            }
            var uiObj = Instantiate(uiData.UIFormsDict[uiFormEnum].uiForm, canvas);
            var uiForm = uiObj.GetComponent<T>();
            if (uiForm == null)
            {
                uiForm = uiObj.AddComponent<T>();
            }
            _uiForms[uiFormEnum] = uiForm;
            _uiForms[uiFormEnum].OnInit();
            _uiForms[uiFormEnum].Order = uiData.UIFormsDict[uiFormEnum].order;
            _uiForms[uiFormEnum].OnOpen(userData);
            RefreshUIFormsOrder();
            return uiForm;
        }

        /// <summary>
        /// 关闭UI窗体
        /// </summary>
        /// <param name="uiFormEnum">关闭的窗口枚举</param>
        public void CloseUIForm(EnumUIForm uiFormEnum)
        {
            if (!_uiForms.ContainsKey(uiFormEnum))return;
            _uiForms[uiFormEnum].Close();
        }

        /// <summary>
        /// 是否存在UI窗体
        /// </summary>
        /// <param name="uiFormEnum">判断的窗口枚举</param>
        /// <returns></returns>
        public bool HasUIForm(EnumUIForm uiFormEnum) => _uiForms.ContainsKey(uiFormEnum);
        
        /// <summary>
        /// 获取UI窗体
        /// </summary>
        /// <param name="uiFormEnum">获取的窗口枚举</param>
        /// <typeparam name="T">对应枚举的窗口类型</typeparam>
        /// <returns>获取的UIForm</returns>
        public T GetUIForm<T>(EnumUIForm uiFormEnum) where T : UIForm
        {
            return _uiForms.GetValueOrDefault(uiFormEnum) as T;
        }

        /// <summary>
        /// 刷新当前已存在的UI窗体的层级
        /// </summary>
        private void RefreshUIFormsOrder()
        {
            var orderByUIForm = _uiForms.Values.OrderBy(uiForm => uiForm.Order).ToList();
            for (int i = 0; i < orderByUIForm.Count; i++)
            {
                orderByUIForm[i].transform.SetSiblingIndex(i);
            }
        }

#if UNITY_EDITOR
        /// <summary>
        /// 测试打开UI窗体的枚举
        /// </summary>
        public EnumUIForm openEnumUIForm;

        [ContextMenu("测试打开UI窗体")]
        private void TestOpenUIForm()
        {
            openEnumUIForm.OpenUIForm("这是测试文本");
        }

        [ContextMenu("测试关闭UI窗体")]
        private void TestCloseUIForm()
        {
            openEnumUIForm.CloseUIForm();
        }
        
        
#endif
    }

    /// <summary>
    /// UI窗体枚举扩展方法
    /// </summary>
    public static class EnumUIFormEx
    {
        /// <summary>
        /// 打开UI窗体
        /// </summary>
        public static UIForm OpenUIForm(this EnumUIForm uiFormEnum, object userData = null) =>
            UIManager.Instance.OpenUIForm(uiFormEnum, userData);
        /// <summary>
        /// 打开UI窗体
        /// </summary>
        public static UIForm OpenUIForm<T>(this EnumUIForm uiFormEnum, object userData = null) where T : UIForm =>
            UIManager.Instance.OpenUIForm<T>(uiFormEnum, userData);
        /// <summary>
        /// 关闭UI窗体
        /// </summary>
        public static void CloseUIForm(this EnumUIForm uiFormEnum) =>
            UIManager.Instance.CloseUIForm(uiFormEnum);
        /// <summary>
        /// 判断UI窗体
        /// </summary>
        public static bool HasUIForm(this EnumUIForm uiFormEnum) =>
            UIManager.Instance.HasUIForm(uiFormEnum);
        /// <summary>
        /// 获取UI窗体
        /// </summary>
        /// <param name="uiFormEnum"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetUIForm<T>(this EnumUIForm uiFormEnum) where T : UIForm =>
            UIManager.Instance.GetUIForm<T>(uiFormEnum);
    }
}